﻿/* 
 * author: www.cnblogs.com/luminji
 * date  : 2011/11/18
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Transactions;
using Luminji.Infrastructure.DomainBase;
using Luminji.Infrastructure.RepositoryFramework;

namespace Luminji.Infrastructure.UnitOfWork
{
    public class UnitOfWork : IUnitOfWork
    {
        private Guid _key;
        private Dictionary<EntityBase, IUnitOfWorkRepository> _addedEntities;
        private Dictionary<EntityBase, IUnitOfWorkRepository> _changedEntities;
        private Dictionary<EntityBase, IUnitOfWorkRepository> _deletedEntities;

        public UnitOfWork()
        {
            this._key = Guid.NewGuid();
            this._addedEntities = new Dictionary<EntityBase,
                                     IUnitOfWorkRepository>();
            this._changedEntities = new Dictionary<EntityBase,
                                       IUnitOfWorkRepository>();
            this._deletedEntities = new Dictionary<EntityBase,
                                       IUnitOfWorkRepository>();
        }

        #region IUnitOfWork Members

        public void RegisterAdded(EntityBase entity,
            IUnitOfWorkRepository repository)
        {
            this._addedEntities.Add(entity, repository);
        }

        public void RegisterChanged(EntityBase entity,
            IUnitOfWorkRepository repository)
        {
            this._changedEntities.Add(entity, repository);
        }

        public void RegisterRemoved(EntityBase entity,
            IUnitOfWorkRepository repository)
        {
            this._deletedEntities.Add(entity, repository);
        }

        public void Commit()
        {
            using (TransactionScope scope = new TransactionScope())
            {
                foreach (EntityBase entity in this._deletedEntities.Keys)
                {
                    this._deletedEntities[entity].PersistDeletedItem(entity);
                }

                foreach (EntityBase entity in this._addedEntities.Keys)
                {
                    this._addedEntities[entity].PersistNewItem(entity);
                }

                foreach (EntityBase entity in this._changedEntities.Keys)
                {
                    this._changedEntities[entity].PersistUpdatedItem(entity);
                }

                scope.Complete();
            }

            this._deletedEntities.Clear();
            this._addedEntities.Clear();
            this._changedEntities.Clear();
            this._key = Guid.NewGuid();
        }

        public object Key
        {
            get { return this._key; }
        }

        #endregion
    }
}
